#include "oled.h"

// 向OLED发送命令
void OLED_WriteCmd(uint8_t cmd) {
    IIC1_Start();
    IIC1_SendAddr(OLED_ADDRESS);     // 发送设备地址
    IIC1_SendByte(OLED_CMD);         // 控制字节：命令模式
    IIC1_SendByte(cmd);              // 命令内容
    IIC1_Stop();
}

// 向OLED发送数据
void OLED_WriteData(uint8_t data) {
    IIC1_Start();
    IIC1_SendAddr(OLED_ADDRESS);     // 发送设备地址
    IIC1_SendByte(OLED_DATA);        // 控制字节：数据模式
    IIC1_SendByte(data);             // 数据内容
    IIC1_Stop();
}

// OLED初始化
void OLED_Init(void) {

    // 初始化I2C
    IIC1_Init();

    // 1.关闭显示
    OLED_WriteCmd(0xAE);

    // 2.设置显示时钟分频因子和振荡器频率
    OLED_WriteCmd(0xD5);
    OLED_WriteCmd(0x80); // 推荐值

    // 3.设置显示偏移（垂直偏移）
    OLED_WriteCmd(0xD3);
    OLED_WriteCmd(0x00);

    // 4.设置显示起始行，0x40表示从第0行开始
    OLED_WriteCmd(0x40);

    // 5.设置地址模式，页寻址模式
    OLED_WriteCmd(0x20);
    OLED_WriteCmd(0x02);

    // 6.设置硬件/软件配置
    OLED_WriteCmd(0xA1); // SEG重映射向左旋转，即横向是从左向右
    OLED_WriteCmd(0xC8); // COM输出扫描方向垂直翻转，原因是屏幕物理连接实际是上下颠倒，即纵向是从上到下

    // 7.设置COM引脚硬件配置
    OLED_WriteCmd(0xDA);
    OLED_WriteCmd(0x12); // 交替模式

    // 8.设置对比度
    OLED_WriteCmd(0x81);
    OLED_WriteCmd(0x80); // 一半亮度

    // 9.设置预充电周期
    OLED_WriteCmd(0xD9);
    OLED_WriteCmd(0x22); // 推荐值 

    // 10.设置VCOMH
    OLED_WriteCmd(0xDB);
    OLED_WriteCmd(0x35); // 推荐值

    // 11.设置电荷泵（SH1106重要设置）
    OLED_WriteCmd(0xAD);
    OLED_WriteCmd(0x8B); // 启用内置DC-DC转换器

    // 12.全屏点亮验证
    OLED_WriteCmd(0xA4);

    // 13.非反色显示
    OLED_WriteCmd(0xA6);

     // 14.对于SH1106，设置列地址范围（132列中显示128列）
    OLED_WriteCmd(0x10); // A7 ~ A4 = 0000
    OLED_WriteCmd(0x02); // A3 ~ A0 = 0010

    // 15.开启显示
    OLED_WriteCmd(0xAF);

    OLED_Clear();

    printf("OLED Init OK\r\n");
}

// 清屏
void OLED_Clear(void) {
    for(uint8_t page = 0; page < OLED_PAGES; page++) {
        OLED_SetCursor(page, 0);
        for(uint8_t col = 0; col < OLED_WIDTH; col++) {
            OLED_WriteData(0x00);
        }
    }
}

// 设置光标位置
void OLED_SetCursor(uint8_t page, uint8_t col) {
    // 设置页地址
    OLED_WriteCmd(0xB0 + page);
    // 设置列地址高4位（+2是因为SH1106有132列，从第2列开始显示）     
    OLED_WriteCmd(0x10 + ((col + 2) >> 4));
    // 设置列地址低4位
    OLED_WriteCmd(0x00 + ((col + 2) & 0x0F));
}

// 定位到某个像素点
void OLED_SetCursorXY(uint8_t x, uint8_t y) {
    // 根据横纵坐标，我们要定位到实际的显示位置
    uint8_t page = y / 8;
    // 确定页地址, 起始页地址是0xB0
    OLED_WriteCmd(0xB0 + page);
    // 确定列地址
    // 设置列地址高4位
    OLED_WriteCmd(0x10 + ((x + 2) >> 4));
    // 设置列地址低4位
    OLED_WriteCmd(0x00 + ((x + 2) & 0x0F));
}

// 点亮单个像素点
void OLED_SetPixel(uint8_t x, uint8_t y) {
    if (x > 127 || y > 63) {
        return;
    }
    OLED_SetCursorXY(x, y);
    uint8_t bit = y % 8;
    uint8_t pixel_data = (1 << bit);
	printf("%d", pixel_data);
    OLED_WriteData(pixel_data);
}

void OLED_DrawLogo() {
	OLED_SetCursorXY(37, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(38, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(39, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(40, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(41, 16);
	OLED_WriteData(0x50);
	OLED_SetCursorXY(42, 16);
	OLED_WriteData(0x30);
	OLED_SetCursorXY(46, 16);
	OLED_WriteData(0xF0);
	OLED_SetCursorXY(47, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(48, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(49, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(50, 16);
	OLED_WriteData(0xF0);
	OLED_SetCursorXY(53, 16);
	OLED_WriteData(0xF0);
	OLED_SetCursorXY(54, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(55, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(56, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(57, 16);
	OLED_WriteData(0x90);
	OLED_SetCursorXY(62, 16);
	OLED_WriteData(0x80);
	OLED_SetCursorXY(63, 16);
	OLED_WriteData(0x60);
	OLED_SetCursorXY(64, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(65, 16);
	OLED_WriteData(0x60);
	OLED_SetCursorXY(66, 16);
	OLED_WriteData(0x80);
	OLED_SetCursorXY(71, 16);
	OLED_WriteData(0xF0);
	OLED_SetCursorXY(72, 16);
	OLED_WriteData(0x80);
	OLED_SetCursorXY(73, 16);
	OLED_WriteData(0x40);
	OLED_SetCursorXY(74, 16);
	OLED_WriteData(0x20);
	OLED_SetCursorXY(75, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(79, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(80, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(81, 16);
	OLED_WriteData(0xF0);
	OLED_SetCursorXY(82, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(83, 16);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(37, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(38, 24);
	OLED_WriteData(0x06);
	OLED_SetCursorXY(39, 24);
	OLED_WriteData(0x05);
	OLED_SetCursorXY(40, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(41, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(42, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(46, 24);
	OLED_WriteData(0x07);
	OLED_SetCursorXY(53, 24);
	OLED_WriteData(0x07);
	OLED_SetCursorXY(54, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(55, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(56, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(57, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(61, 24);
	OLED_WriteData(0x06);
	OLED_SetCursorXY(62, 24);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(63, 24);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(64, 24);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(65, 24);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(66, 24);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(67, 24);
	OLED_WriteData(0x06);
	OLED_SetCursorXY(71, 24);
	OLED_WriteData(0x07);
	OLED_SetCursorXY(73, 24);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(74, 24);
	OLED_WriteData(0x02);
	OLED_SetCursorXY(75, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(79, 24);
	OLED_WriteData(0x02);
	OLED_SetCursorXY(80, 24);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(81, 24);
	OLED_WriteData(0x07);
	OLED_SetCursorXY(53, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(54, 32);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(55, 32);
	OLED_WriteData(0x0C);
	OLED_SetCursorXY(56, 32);
	OLED_WriteData(0x42);
	OLED_SetCursorXY(57, 32);
	OLED_WriteData(0x4C);
	OLED_SetCursorXY(58, 32);
	OLED_WriteData(0x08);
	OLED_SetCursorXY(59, 32);
	OLED_WriteData(0x4C);
	OLED_SetCursorXY(60, 32);
	OLED_WriteData(0x42);
	OLED_SetCursorXY(61, 32);
	OLED_WriteData(0x0C);
	OLED_SetCursorXY(62, 32);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(63, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(67, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(68, 32);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(69, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(70, 32);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(71, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(73, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(74, 32);
	OLED_WriteData(0x50);
	OLED_SetCursorXY(75, 32);
	OLED_WriteData(0x60);
	OLED_SetCursorXY(77, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(78, 32);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(79, 32);
	OLED_WriteData(0x10);
	OLED_SetCursorXY(80, 32);
	OLED_WriteData(0xE0);
	OLED_SetCursorXY(53, 40);
	OLED_WriteData(0x03);
	OLED_SetCursorXY(54, 40);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(55, 40);
	OLED_WriteData(0x09);
	OLED_SetCursorXY(56, 40);
	OLED_WriteData(0x0A);
	OLED_SetCursorXY(57, 40);
	OLED_WriteData(0x0A);
	OLED_SetCursorXY(58, 40);
	OLED_WriteData(0x09);
	OLED_SetCursorXY(59, 40);
	OLED_WriteData(0x0A);
	OLED_SetCursorXY(60, 40);
	OLED_WriteData(0x0A);
	OLED_SetCursorXY(61, 40);
	OLED_WriteData(0x09);
	OLED_SetCursorXY(62, 40);
	OLED_WriteData(0x04);
	OLED_SetCursorXY(63, 40);
	OLED_WriteData(0x03);
	OLED_SetCursorXY(67, 40);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(69, 40);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(71, 40);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(74, 40);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(75, 40);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(78, 40);
	OLED_WriteData(0x01);
	OLED_SetCursorXY(79, 40);
	OLED_WriteData(0x01);
}
